package Player
{
	import Events.SnakeChangeEvent;
	
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.Timer;

	/**
	 * Class to model for the head of each snake
	 * Position is saved, as well ass radius(line thickness/head size)
	 * The timer is used to stop drawing the line for a jump simulation
	 */ 
	public class SnakeHead extends EventDispatcher
	{
		// Default head colors for all snakes
		private static const DEFAULT_HEAD_COLOR:uint = 0xFFFF33;
		private static const INVERTED_HEAD_COLOR:uint = 0x0000FF;
		
		// Color for head and tail
		private var _tailColor:uint;
		private var _headColor:uint;
		
		// X and y of snake
		private var _position:Point = new Point(0,0);
		
		// Orientation of snake
		private var _orientation:Point = new Point(0,1);
		
		// Line thickness or head width
		private var _thickness:Number = 3;
		
		// Normal is round head, with 90 degree corners,
		// Rectangular head is drawed
		private var _roundHead:Boolean = true;
		
		// Pixel moment per timer event
		private var _speed:Number = 2;
		private var _rotationSpeed:Number = 5;
		
		public function SnakeHead(tailColor:uint)
		{
			_headColor = DEFAULT_HEAD_COLOR;
			_tailColor = tailColor;
			
			// Rotate to 120 degrees
			rotate(-60);
		}
		
		public function updateSnake(timePassed:Number):void{			
			// Story old position to draw line
			var oldPosition:Point = position.clone();
			
			// Add position in orientation direction
			var movement:Point = _orientation.clone();
			movement.normalize(_speed * timePassed);
			
			// Add to position
			_position = _position.add(movement);
			dispatchEvent(new SnakeChangeEvent(SnakeChangeEvent.SNAKE_MOVE,this,oldPosition));
		}
		
		// Convert degrees to radians
		private function degToRadian(degrees:Number):Number{
			return (degrees * (Math.PI/180));
		}
		
		// Rotate snake
		private function rotate(degrees:Number):void{
			var matrix:Matrix = new Matrix();
			matrix.rotate(degToRadian(degrees));
			_orientation = matrix.transformPoint(_orientation);
			_orientation.normalize(1);
		}
		
		public function turnSnakeLeft(timePassed:Number):void{
			rotate(-_rotationSpeed * timePassed);
		}
		
		public function turnSnakeRight(timePassed:Number):void{
			rotate(_rotationSpeed * timePassed);
		}
		
		/**
		 * Function to set different colored head on control inversion
		 */
		public function setInvertedHead(enabled:Boolean = true):void{
			if(enabled){
				_headColor = INVERTED_HEAD_COLOR;
			}else{
				_headColor = DEFAULT_HEAD_COLOR;
			}
			dispatchEvent(new SnakeChangeEvent(SnakeChangeEvent.HEAD_CHANGE,this,position));
		}
		
		/**
		 * Function to change head shape from round to rectangular or back
		 */
		public function setRoundHead(enabled:Boolean = true):void{
			_roundHead = enabled;
			dispatchEvent(new SnakeChangeEvent(SnakeChangeEvent.HEAD_CHANGE,this,position));
		}
		
		/**
		 * Method to check if snake has a normal head or a rectangular one
		 */
		public function get roundHead():Boolean{
			return _roundHead;
		}
		
		public function get tailColor():uint{
			return _tailColor;
		}
		public function get headColor():uint{
			return _headColor;
		}
		
		public function get position():Point{
			return _position;
		}
		
		public function get orientation():Point{
			return _orientation;
		}
		
		public function get thickness():Number{
			return _thickness;
		}
	}
}